home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
elk-2_0.lha
/
elk-2.0
/
src
/
load.ld.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-16
|
3KB
|
143 lines
#include <a.out.h>
#include <sys/types.h>
#ifdef ECOFF
# ifdef CACHECTL_H
# include CACHECTL_H
# endif
struct headers {
struct filehdr fhdr;
struct aouthdr aout;
struct scnhdr section[3];
};
#endif
extern char *sbrk();
static char Loader_Output[20];
Load_Object (names) Object names; {
#ifdef ECOFF
struct headers hdr;
#else
struct exec hdr;
#endif
register char *brk, *obrk, *lp, *li;
char *buf;
register n, f, len, liblen;
Object port, tail, fullnames, libs;
FILE *fp;
extern char *mktemp();
GC_Node3;
Alloca_Begin;
li = Loader_Input;
if (li[0] == 0)
li = A_Out_Name;
strcpy (Loader_Output, "/tmp/ldXXXXXX");
(void)mktemp (Loader_Output);
port = tail = fullnames = Null;
GC_Link3 (port, tail, fullnames);
for (len = 0, tail = names; !Nullp (tail); tail = Cdr (tail)) {
port = General_Open_File (Car (tail), P_INPUT, Var_Get (V_Load_Path));
fullnames = Cons (PORT(port)->name, fullnames);
len += STRING(Car (fullnames))->size + 1;
(void)P_Close_Input_Port (port);
}
GC_Unlink;
libs = Var_Get (V_Load_Libraries);
if (TYPE(libs) == T_String) {
liblen = STRING(libs)->size;
lp = STRING(libs)->data;
} else {
liblen = 3; lp = "-lc";
}
Alloca (buf, char*, strlen (A_Out_Name) + len + liblen + 100);
obrk = brk = sbrk (0);
brk = (char *)((int)brk + 7 & ~7);
#if defined(hp9000s300) || defined(__hp9000s300__)
sprintf (buf, "ld -N%s -A %s -R %x -o %s ",
#else
sprintf (buf, "ld -N%s -A %s -T %x -o %s ",
#endif
#ifdef USE_XFLAG
" -x",
#else
"",
#endif
li, (unsigned)brk, Loader_Output);
for (tail = fullnames; !Nullp (tail); tail = Cdr (tail)) {
register struct S_String *str = STRING(Car (tail));
strncat (buf, str->data, str->size);
strcat (buf, " ");
}
strncat (buf, lp, liblen);
if (Verbose)
printf ("[%s]\n", buf);
if (system (buf) != 0) {
(void)unlink (Loader_Output);
Primitive_Error ("system linker failed");
}
Disable_Interrupts; /* To ensure that f gets closed */
if ((f = open (Loader_Output, 0)) == -1) {
(void)unlink (Loader_Output);
Primitive_Error ("cannot open tempfile");
}
if (Loader_Input[0])
(void)unlink(Loader_Input);
strcpy (Loader_Input, Loader_Output);
if (read (f, (char *)&hdr, sizeof (hdr)) != sizeof (hdr)) {
err:
close (f);
Primitive_Error ("corrupt tempfile (`ld' is broken)");
}
#ifdef ECOFF
n = hdr.aout.tsize + hdr.aout.dsize + hdr.aout.bsize;
#else
n = hdr.a_text + hdr.a_data + hdr.a_bss;
#endif
n += brk - obrk;
if (sbrk (n) == (char *)-1) {
close (f);
Primitive_Error ("not enough memory to load object file");
}
bzero (obrk, n);
#ifdef ECOFF
n -= hdr.aout.bsize;
(void)lseek (f, (long)hdr.section[0].s_scnptr, 0);
#else
n -= hdr.a_bss;
#endif
if (read (f, brk, n) != n)
goto err;
if ((fp = fdopen (f, "r")) == NULL) {
close (f);
Primitive_Error ("cannot fdopen object file");
}
if (The_Symbols)
Free_Symbols (The_Symbols);
The_Symbols = Snarf_Symbols (fp, &hdr);
(void)fclose (fp);
#if defined(ECOFF) && defined(CACHECTL_H)
if (cacheflush (brk, n, BCACHE) < 0)
Primitive_Error ("cacheflush failed: ~E");
#endif
if (!Call_Initializers (The_Symbols, brk))
Primitive_Error ("no initializers in object file(s)");
Enable_Interrupts;
Alloca_End;
}
Finit_Load () {
if (Loader_Input[0])
(void)unlink (Loader_Input);
}